﻿#include "opencv2\opencv.hpp"
#include "opencv2\imgproc.hpp"
#include "core.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
	const char* fn = "D:\\opencv class\\米粒图.png";
	Mat image = imread(fn);
	
	//滤波处理
	Mat gray_image;
	cvtColor(image, gray_image, COLOR_BGR2GRAY);

	Mat gauss_image;
	GaussianBlur(gray_image, gauss_image, Size(3, 3), 0);

	Mat adp_image;
	adaptiveThreshold(gauss_image, adp_image, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 41, -25);
	imshow("局部阈值划分", adp_image);
	
	//寻找轮廓
	Mat seg = adp_image.clone();
	vector<vector<Point>> cnts;
	findContours(seg, cnts, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
	drawContours(image, cnts, -1, Scalar(0, 0, 255));

	
	int count = 0;
	double areas[200];
	double lengths[200];
	double sum_area = 0;
	double sum_length = 0;
	//画出米粒坐标
	for (int i = cnts.size() - 1; i >= 0; i--)
	{
		vector<Point> c = cnts[i];
		double area = contourArea(c);
		double len = arcLength(c, true);
		if (area < 10)
		{
			continue;
		}
		areas[count] = area;
		lengths[count] = len;
		count++;
		sum_area += area;
		sum_length += len;
		//得到轮廓包围矩形
		Rect rect = boundingRect(c);
		rectangle(image, rect, Scalar(255, 255, 255), 1);

		//标出米粒坐标
		stringstream ss;
		string strcount;
		ss << count;
		ss >> strcount;
		putText(image, strcount, Point(rect.x, rect.y), CV_FONT_HERSHEY_PLAIN, 0.5, Scalar(0, 255, 0));
	}
	double average_len = sum_length / count;
	double average_area = sum_area / count;
	cout << "米粒数量：" << count << endl;
	cout << "平均面积：" << average_area << endl;
	cout << "平均长度：" << average_len << endl;

	//计算标准差
	double std_len = 0, std_area = 0;
	for (int i = 0; i < count; i++)
	{
		std_area += (areas[i] - average_area) * (areas[i] - average_area)/count;
		std_len += (lengths[i] - average_len) * (lengths[i] - average_len) / count;
	}
	std_area = sqrt(std_area);
	std_len = sqrt(std_len);
	cout << "面积标准差：" << std_area << endl;
	cout << "周长标准差：" << std_len << endl;

	int valid_num = 0;
	for (int i = 0; i < count; i++)
	{
		if(areas[i] > (average_area - 3 * std_area)
			&& areas[i] < (average_area + 3 * std_area)
			&& lengths[i] > (average_len - 3 * std_len)
			&& lengths[i] < (average_len + 3 * std_len))
		{
			valid_num ++;
		}
	}
	cout << "面积周长3smage内的比例：" << (float)valid_num/count << endl;
	imshow("原始图像", image);
	waitKey(0);
	destroyAllWindows();
}